package dyl.sys.quartz;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import dyl.common.util.JdbcTemplateUtil;
import dyl.sys.bean.SysQuartz;



public class QuartzManager implements BeanFactoryAware {
	private Logger log = Logger.getLogger(QuartzManager.class);
	private Scheduler scheduler;
	private static BeanFactory beanFactory = null;
	@Resource
	private JdbcTemplateUtil jdbcTemplate;

	@SuppressWarnings("unused")
	private void reScheduleJob() throws Exception, ParseException {
		    List<SysQuartz> sysQuartzList =  jdbcTemplate.queryForListBean("select * from sys_quartz t", SysQuartz.class);
		    for(SysQuartz sq:sysQuartzList){
		    	configQuatrz(sq);
		    }
		}

		public boolean configQuatrz(SysQuartz sysQuartz) {
			boolean result = false;
			try {
				// 运行时可通过动态注入的scheduler得到trigger
				CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(
						sysQuartz.getTriggername(), Scheduler.DEFAULT_GROUP);
				// 如果计划任务已存在则调用修改方法
				if (trigger != null) {
					change(sysQuartz, trigger);
				} else {
					// 如果计划任务不存在并且数据库里的任务状态为可用时,则创建计划任务
					if (sysQuartz.getState().intValue()==1) {
						this.createCronTriggerBean(sysQuartz);
					}
				}
				result = true;
			} catch (Exception e) {
				result = false;
				e.printStackTrace();
			}

			return result;
		}

		public void change(SysQuartz sysQuartz, CronTriggerBean trigger)
				throws Exception {
			// 如果任务为可用
			if (sysQuartz.getState().intValue()==1) {
				// 判断从DB中取得的任务时间和现在的quartz线程中的任务时间是否相等
				// 如果相等，则表示用户并没有重新设定数据库中的任务时间，这种情况不需要重新rescheduleJob
				if (!trigger.getCronExpression().equalsIgnoreCase(sysQuartz.getCronexpression())){
					trigger.setCronExpression(sysQuartz.getCronexpression());
					scheduler.rescheduleJob(sysQuartz.getTriggername(),
							Scheduler.DEFAULT_GROUP, trigger);
					log.info(new Date() + ": 更新" + sysQuartz.getTriggername() + "计划任务");
				}
			} else {
				// 不可用
				scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());//停止触发器
				scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());//移除触发器
				scheduler.deleteJob(trigger.getJobName(), trigger.getJobGroup());//删除任务
				log.info(new Date() + ": 删除" + sysQuartz.getTriggername() + "计划任务");
			}

		}

		/**
		 * 创建/添加计划任务
		 * 
		 * @param sysQuartz
		 *            计划任务配置对象
		 * @throws Exception
		 */
		public void createCronTriggerBean(SysQuartz sysQuartz) throws Exception {
			// 新建一个基于Spring的管理Job类
			MethodInvokingJobDetailFactoryBean mjdfb = new MethodInvokingJobDetailFactoryBean();
			mjdfb.setName(sysQuartz.getJobdetailname());// 设置Job名称
			
			//mjdfb.setTargetObject(Class.forName(sysQuartz.getTargetobject()).newInstance());// 设置任务类
			
			mjdfb.setTargetObject(beanFactory.getBean(sysQuartz.getTargetobject()));
			 
			mjdfb.setTargetMethod(sysQuartz.getMethodname());// 设置任务方法
			mjdfb.setConcurrent(sysQuartz.getConcurrent().intValue()!=0); // 设置是否并发启动任务
			mjdfb.afterPropertiesSet();// 将管理Job类提交到计划管理类
			// 将Spring的管理Job类转为Quartz管理Job类
			JobDetail jobDetail = new JobDetail();
			jobDetail = (JobDetail) mjdfb.getObject();
			jobDetail.setName(sysQuartz.getJobdetailname());
			scheduler.addJob(jobDetail, true); // 将Job添加到管理类
			// 新一个基于Spring的时间类
			CronTriggerBean c = new CronTriggerBean();
			c.setCronExpression(sysQuartz.getCronexpression());// 设置时间表达式
			c.setName(sysQuartz.getTriggername());// 设置名称
			c.setJobDetail(jobDetail);// 注入Job
			c.setJobName(sysQuartz.getJobdetailname());// 设置Job名称
			scheduler.scheduleJob(c);// 注入到管理类
			scheduler.rescheduleJob(sysQuartz.getTriggername(), Scheduler.DEFAULT_GROUP,c);// 刷新管理类
			log.info(new Date() + ": 新建" + sysQuartz.getTriggername() + "计划任务");
		}

		public Scheduler getScheduler() {
			return scheduler;
		}

		public void setScheduler(Scheduler scheduler) {
			this.scheduler = scheduler;
		}

		public void setBeanFactory(BeanFactory factory) throws BeansException {
			this.beanFactory = factory;

		}

		public BeanFactory getBeanFactory() {
			return beanFactory;
		}
	   
	}
